home *** CD-ROM | disk | FTP | other *** search
/ Amiga Inside! / Amiga FD Inside (1995)(Ultramax).iso / berndspd / systemtools / appcon / src / appcon.c next >
C/C++ Source or Header  |  1994-05-14  |  15KB  |  593 lines

  1. /* AppCon Main Source
  2. **
  3. ** Done by Stephan Fuhrmann
  4. **
  5. */
  6.  
  7. #define MTYPE_APPWINDOW 7
  8. #define EXEC_MINIMUM 36
  9. #define MY_ID 3111973
  10. /*#define DEBUG_ME*/
  11.  
  12. #include <AppCon.h>
  13. #include <dos.h>
  14. //#include <stdio.h>
  15. //#include <stdlib.h>
  16.  
  17. #define FILENAME_MAX 128
  18.  
  19. #include <string.h>
  20.  
  21. #include <dos/dos.h>
  22. #include <dos/dosextens.h>
  23. #include <exec/execbase.h>
  24. #include <exec/ports.h>
  25. #include <exec/io.h>
  26. #include <exec/libraries.h>
  27. #include <exec/memory.h>
  28. #include <exec/interrupts.h>
  29. #include <exec/tasks.h>
  30. #include <devices/console.h>
  31. #include <devices/conunit.h>
  32. #include <devices/keymap.h>
  33. #include <devices/input.h>
  34. #include <devices/inputevent.h>
  35. #include <devices/timer.h>
  36. #include <intuition/intuition.h>
  37. #include <intuition/intuitionbase.h>
  38. #include <workbench/startup.h>
  39. #include <workbench/workbench.h>
  40.  
  41. #ifdef LATTICE
  42. int CXBRK(void) { return(0); }
  43. int chkabort(void) { return(0); }
  44. #endif
  45.  
  46. struct ExecBase *SysBase;
  47. struct IntuitionBase *IntuitionBase;
  48. struct Library *WorkbenchBase;
  49. struct Library *KeymapBase;
  50. struct DosLibrary *DOSBase;
  51. struct Library *UtilityBase;
  52.  
  53. #include <proto/exec.h>
  54. #include <proto/dos.h>
  55. #include <proto/intuition.h>
  56. #include <proto/wb.h>
  57. #include <proto/keymap.h>
  58. #include <proto/utility.h>
  59.  
  60. long timeout=10;    /* in tenths of a second */
  61.  
  62. const char vt[]=VERSTAG;
  63.  
  64. struct Process *AppConTask=0L;
  65. struct CommandLineInterface *AppCLI;
  66. struct Window *AppConWindow;
  67.  
  68. struct MsgPort *timeport=0L;
  69. struct MsgPort *appport=0L;
  70. struct MsgPort *ioreply=0L;
  71. struct IOStdReq *iorequest=0L;
  72. struct timerequest *timerio=0L;
  73.  
  74. struct AppWindow *AppWindow;
  75.  
  76. struct AppMessage *AppMessage;
  77.  
  78. struct InputEvent *InputEvent;
  79.  
  80. ULONG WaitSignals=SIGBREAKF_CTRL_C;
  81. ULONG ReceivedSignals;
  82.  
  83. char filename[FILENAME_MAX];
  84. char dirname[FILENAME_MAX];
  85. char pathname[FILENAME_MAX*2];
  86.  
  87. char AppConName[]="AppCon";
  88.  
  89. #define TEMPLATE    "TimeOut=Time/K/N"
  90. enum templates {OPT_TIMEOUT,OPT_COUNT};
  91.  
  92. LONG opts[OPT_COUNT];
  93.  
  94. char HelpPage[]=
  95.     "\nAppCon Help\n"\
  96.     "-----------\n"\
  97.     "© 1994 Stephan Fuhrmann\n\n"\
  98.     "Options\n"\
  99.     "---------\n"\
  100.     "TIMEOUT...timeout between checks of window closing, in tenths of a second\\NUMBER\n"\
  101.     "\nExample: AppCon TIMEOUT=10\n";
  102.  
  103. int breakother (struct Process *MyProc);
  104. struct InputEvent *SendEvents (struct IOStdReq *iorequest,struct InputEvent *SendUs);
  105. void MakeActive (struct Window *ActivateMe);
  106. struct InputEvent *BrewInputevent(char *ASCII);
  107. void FreeIEs (struct InputEvent *firstie);
  108. struct Window *GetConWindow (struct Process *ConProcess,struct MsgPort *MyPort);
  109. long AntiBlocking (struct Window *MyWin);
  110. void MegaAbort (struct IOStdReq *);
  111. void LaunchRequest (long secs,long micros,struct timerequest *mytimerio);
  112.  
  113. __saveds int main(int argc,char *argv)
  114. {
  115.     struct RDArgs *argsptr;
  116.     APTR oldname;
  117.  
  118.     SysBase=*(struct ExecBase **)4;
  119.  
  120.     AppConTask=(struct Process *) FindTask(NULL);
  121.  
  122.     oldname=AppConTask->pr_Task.tc_Node.ln_Name;
  123.     AppConTask->pr_Task.tc_Node.ln_Name=AppConName;
  124.  
  125.     if (!argc)
  126.         return (0);
  127.  
  128.     if (DOSBase=(struct DosLibrary *)OpenLibrary ("dos.library",37))
  129.     {
  130.         PutStr (VSTRING);
  131.         PutStr ("PUBLIC DOMAIN written 1993/94 by Stephan Fuhrmann\n");
  132.  
  133.         if (IntuitionBase=(struct IntuitionBase *)OpenLibrary ("intuition.library",37))
  134.         {
  135.             if (WorkbenchBase=OpenLibrary ("workbench.library",37))
  136.             {
  137.                 if (KeymapBase=OpenLibrary ("keymap.library",37))
  138.                 {
  139.                     if (UtilityBase=OpenLibrary ("utility.library",37))
  140.                     {
  141.                         if (breakother (AppConTask))
  142.                         {
  143.                             argsptr=AllocDosObject (DOS_RDARGS,0);
  144.     
  145.                             if (argsptr)
  146.                             {
  147.                                 argsptr->RDA_ExtHelp=HelpPage;
  148.     
  149.                                 if (!ReadArgs (TEMPLATE,opts,argsptr))
  150.                                 {
  151.                                     PrintFault (IoErr(),NULL);
  152.                                     FreeArgs (argsptr);
  153.                                     FreeDosObject (DOS_RDARGS,argsptr);
  154.                                     return (0);
  155.                                 }
  156.                 
  157.                                 if (opts[OPT_TIMEOUT])
  158.                                     timeout=*(LONG *)opts[OPT_TIMEOUT];
  159.     
  160.                                 if ((ioreply=CreateMsgPort()) && (appport=CreateMsgPort()) && (timeport=CreateMsgPort()))
  161.                                 {
  162.                                     appport->mp_Node.ln_Name=AppConName;
  163.     
  164.                                     WaitSignals |= 1L << (ioreply->mp_SigBit);
  165.                                     WaitSignals |= 1L << (timeport->mp_SigBit);
  166.                                     WaitSignals |= 1L << (appport->mp_SigBit);
  167.     
  168.                                     if ((iorequest=CreateIORequest(ioreply,sizeof(struct IOStdReq)))
  169.                                        && (timerio=CreateIORequest(timeport,sizeof(struct timerequest))))
  170.                                     {
  171.             
  172.                                         if (!OpenDevice ("timer.device",UNIT_VBLANK,(struct IORequest *)timerio,0))
  173.                                         {
  174.                             
  175.                                             if (!OpenDevice ("input.device",0L,(struct IORequest *)iorequest,0))
  176.                                             {
  177.     
  178.                                                 AppConWindow=GetConWindow (AppConTask,ioreply);
  179.         
  180.                                                 if (AppConWindow)
  181.                                                 {
  182.                                                     if (AppWindow=AddAppWindowA (MY_ID,NULL,AppConWindow,appport,NULL))
  183.                                                     {
  184.                                                         ReceivedSignals=0;
  185.         
  186.                                                         LaunchRequest (timeout / 10,(timeout % 10) * 100000,timerio);
  187.             
  188.                                                         while (!(ReceivedSignals & SIGBREAKF_CTRL_C))
  189.                                                         {
  190.                                                             ReceivedSignals=Wait (WaitSignals);
  191.     
  192.                                                             if (ReceivedSignals & (1L << (timeport->mp_SigBit)))
  193.                                                             {
  194.                                                                 ReceivedSignals &= ~ (1L << (timeport->mp_SigBit));
  195.         
  196.                                                                 MegaAbort ((struct IOStdReq *)timerio);
  197.                                                                 LaunchRequest (timeout / 10,(timeout % 10) * 100000,timerio);
  198.         
  199.                                                                 if (AntiBlocking (AppConTask->pr_ConsoleTask) <= 1)
  200.                                                                     Signal ((struct Task *)AppConTask,SIGBREAKF_CTRL_C);
  201.                                                             }
  202.         
  203.                                                             if (ReceivedSignals & (1L << (appport->mp_SigBit)))
  204.                                                             {
  205.                                                                 ReceivedSignals &= ~ (1L << (appport->mp_SigBit));
  206.             
  207.                                                                 while (AppMessage = (struct AppMessage *)GetMsg (appport))
  208.                                                                 {
  209.                                                                     register long cnt,max;
  210.                                                                     register struct WBArg *curarg;
  211.                                                                     struct WBArg *argptr;
  212.             
  213.                                                                     if ((AppMessage->am_Type)!=MTYPE_APPWINDOW)
  214.                                                                     {
  215. #ifdef DEBUG_ME
  216.                                                                         VPrintf ("Unknown type (%ld)!",&AppMessage->am_Type);
  217. #endif        
  218.                                                                         ReplyMsg((struct Message *)AppMessage);
  219.                                                                         continue;
  220.                                                                     }
  221.     
  222.                                                                     max=AppMessage->am_NumArgs;
  223.                                                                     curarg=AppMessage->am_ArgList;
  224.         
  225.                                                                     if (!max)
  226.                                                                     {
  227. #ifdef DEBUG_ME
  228.                                                                         VPrintf   ("Not enough arguments (%ld)!",&max);
  229. #endif    
  230.                                                                         ReplyMsg((struct Message *)AppMessage);
  231.                                                                         continue;
  232.                                                                     }
  233.     
  234.                                                                     argptr=curarg;
  235.         
  236.                                                                     for (cnt=0;cnt<max;cnt++)
  237.                                                                     {
  238.                                                                         int hasspace;
  239.                                                                         int plusend;
  240.     
  241.                                                                         if (argptr->wa_Lock)
  242.                                                                             NameFromLock(argptr->wa_Lock,dirname,FILENAME_MAX);
  243.         
  244.                                                                         strcpy (pathname,dirname);
  245.                 
  246.                                                                         if (argptr->wa_Name)
  247.                                                                             AddPart(pathname,argptr->wa_Name,FILENAME_MAX*2);
  248.     
  249.                                                                         if (cnt)
  250.                                                                         {
  251.                                                                             if (InputEvent=BrewInputevent (" "))
  252.                                                                             {
  253.                                                                                 MakeActive (AppConWindow);
  254.                 
  255.                                                                                 FreeIEs(SendEvents (iorequest,InputEvent));
  256.                                                                             }
  257.                                                                             else
  258.                                                                                 DisplayBeep(0);
  259.                                                                         }
  260.             
  261.                                                                         hasspace=(int)strchr(pathname,' ');
  262.                                                                         plusend=*(pathname+strlen(pathname)-1)=='+';
  263.     
  264.                                                                         if (hasspace || plusend)
  265.                                                                         {
  266.                                                                             if (InputEvent=BrewInputevent ("\""))
  267.                                                                             {
  268.                                                                                 MakeActive (AppConWindow);
  269.             
  270.                                                                                 FreeIEs(SendEvents (iorequest,InputEvent));
  271.                                                                             }
  272.                                                                             else
  273.                                                                                 DisplayBeep(0);
  274.                                                                         }
  275.         
  276.                                                                         if (InputEvent=BrewInputevent (pathname))
  277.                                                                         {
  278.                                                                             MakeActive (AppConWindow);
  279.             
  280.                                                                             FreeIEs (SendEvents (iorequest,InputEvent));
  281.                                                                         }
  282.                                                                         else
  283.                                                                             DisplayBeep (0);
  284.                                                     
  285.                                                                         if (hasspace || plusend)
  286.                                                                         {
  287.                                                                             if (InputEvent=BrewInputevent ("\""))
  288.                                                                             {
  289.                                                                                 MakeActive (AppConWindow);
  290.             
  291.                                                                                 FreeIEs(SendEvents (iorequest,InputEvent));
  292.                                                                             }
  293.                                                                             else
  294.                                                                                 DisplayBeep (0);
  295.                                                                         }
  296.                                                                         argptr++;
  297.                                                                     }
  298.     
  299.                                                                     ReplyMsg((struct Message *)AppMessage);
  300.                                                                 }
  301.                                                             }
  302.                                                         }
  303.                                                         RemoveAppWindow (AppWindow);
  304.                                                     }
  305.                                                     else
  306.                                                         PutStr ("Couldn't add AppWindow\n");
  307.                                                 }
  308.                                                 else
  309.                                                     PutStr ("Couldn't find console window!\n");
  310.  
  311.                                                 MegaAbort (iorequest);
  312.     
  313.                                                 CloseDevice ((struct IORequest *)iorequest);
  314.                                             }
  315.                                             else
  316.                                                 PutStr ("Couldn't open console.device");
  317.     
  318.                                             MegaAbort ((struct IOStdReq *)timerio);
  319.                                             CloseDevice ((struct IORequest *)timerio);
  320.                                         }
  321.                                         else
  322.                                             PutStr ("Couldn't open timer.device\n");
  323.                                     }
  324.                                     else
  325.                                         PutStr ("Couldn't create IORequest\n");
  326.         
  327.                                     DeleteIORequest (timerio);
  328.                                     DeleteIORequest (iorequest);
  329.                                 }
  330.                                 else
  331.                                     PutStr ("Couldn't create msgport\n");
  332.  
  333.                                 DeleteMsgPort (timeport);            
  334.                                 DeleteMsgPort (ioreply);
  335.                                 DeleteMsgPort (appport);
  336.                             }    
  337.                             else
  338.                                 PutStr ("Couldn't allocate ReadArgs-Object\n");
  339.  
  340.                             FreeArgs (argsptr);
  341.  
  342.                             if (argsptr)
  343.                                 FreeDosObject (DOS_RDARGS,argsptr);
  344.                         }
  345.                         else
  346.                             PutStr ("Removed existing AppCon-Task.\n");
  347.  
  348.                         CloseLibrary (UtilityBase);
  349.                     }
  350.                     CloseLibrary (KeymapBase);
  351.                 }
  352.                 CloseLibrary (WorkbenchBase);
  353.             }
  354.             CloseLibrary ((struct Library *)IntuitionBase);
  355.         }
  356.  
  357.         CloseLibrary ((struct Library *)DOSBase);
  358.     }
  359.  
  360.     AppConTask->pr_Task.tc_Node.ln_Name=oldname;
  361.  
  362.     return (0);
  363. }
  364.  
  365. int breakother (struct Process *MyProc)
  366. {
  367.     struct List *MyList;
  368.     struct Process *ProcPtr;
  369.     APTR MyConTask;
  370.     UWORD cnt;
  371.     int result=1;
  372.  
  373.     /* critical sections start */
  374.     Forbid();
  375.  
  376.     MyConTask=MyProc->pr_ConsoleTask;
  377.  
  378.     for (cnt=0;cnt<2;cnt++)
  379.     {
  380.         MyList=cnt ? &SysBase->TaskReady : &SysBase->TaskWait;
  381.  
  382.         for (ProcPtr=(struct Process *)MyList->lh_Head ;
  383.                 ProcPtr->pr_Task.tc_Node.ln_Succ!=MyList->lh_Tail ;
  384.                 ProcPtr=(struct Process *)ProcPtr->pr_Task.tc_Node.ln_Succ)
  385.         {
  386.             if (ProcPtr->pr_Task.tc_Node.ln_Type==NT_PROCESS)
  387.             {
  388.                 if ((ProcPtr->pr_ConsoleTask==MyConTask) && (ProcPtr!=MyProc))
  389.                 {
  390.                     if (!strcmp(ProcPtr->pr_Task.tc_Node.ln_Name,AppConName))
  391.                     {
  392.                         Signal ((struct Task *)ProcPtr,SIGBREAKF_CTRL_C);
  393.                         result=0;
  394.                     }
  395.                 }
  396.             }
  397.         }
  398.     }
  399.  
  400.     Permit();
  401.     /* critical section end */
  402.  
  403.     return (result);
  404. }
  405.  
  406. struct InputEvent *SendEvents (struct IOStdReq *iorequest,struct InputEvent *SendUs)
  407. {
  408.     struct InputEvent *ThisEvent,*NextEvent;
  409.     
  410.     ThisEvent=SendUs;
  411.     
  412.     while (ThisEvent)
  413.     {
  414.         iorequest->io_Command=IND_WRITEEVENT;
  415.         iorequest->io_Length=sizeof(struct InputEvent);
  416.         iorequest->io_Data=ThisEvent;
  417.         NextEvent=ThisEvent->ie_NextEvent;
  418.         ThisEvent->ie_NextEvent=0L;
  419.         __emit (0x48e7);
  420.         __emit (0xfffe);
  421.         DoIO ((struct IORequest *)iorequest);
  422.         __emit (0x4cdf);
  423.         __emit (0x7fff);
  424.         ThisEvent->ie_NextEvent=NextEvent;        /* recover NextEvent-field for later FreeMem-stuff */
  425.         ThisEvent=NextEvent;
  426.     }
  427.  
  428.     return (SendUs);
  429. }
  430.  
  431. void MakeActive (struct Window *ActivateMe)
  432. {
  433.     if (! ((ActivateMe->Flags) & WFLG_WINDOWACTIVE))
  434.     {
  435.         ActivateWindow (ActivateMe);
  436.         while (! ((ActivateMe->Flags) & WFLG_WINDOWACTIVE))
  437.             Delay (1);
  438.     }
  439. }
  440.  
  441. void FreeIEs (struct InputEvent *firstie)
  442. {
  443.     register struct InputEvent *nextie;
  444.  
  445.     while (firstie)
  446.     {
  447.         nextie=firstie->ie_NextEvent;
  448.         FreeMem (firstie,sizeof (struct InputEvent));
  449.         firstie=nextie;
  450.     }
  451. }
  452.  
  453. struct InputEvent *BrewInputevent(char *ASCII)
  454. {
  455.     struct InputEvent *thisie,*oldie,*grandpa,*firstie;
  456.     register long cnt;
  457.     long junksize;
  458.     WORD *junkbuf;
  459.     long rawsize;
  460.  
  461.     firstie=0;
  462.     thisie=0;
  463.     oldie=0;
  464.  
  465.     junksize=strlen(ASCII)*3;
  466.  
  467.     if (!(junkbuf=AllocVec(junksize*sizeof(WORD),MEMF_CLEAR|MEMF_PUBLIC)))
  468.         return (0);
  469.  
  470.     rawsize=MapANSI (ASCII,strlen(ASCII),(STRPTR)junkbuf,junksize,0);
  471.  
  472.     switch (rawsize)
  473.     {
  474.         case 0:
  475.         case -1:
  476.         case -2:
  477.             FreeVec (junkbuf);
  478.             return (0);
  479.     }
  480.  
  481.     for (cnt=0;cnt<rawsize;cnt++)
  482.     {
  483.         grandpa=oldie;
  484.         oldie=thisie;
  485.  
  486.         thisie=AllocMem(sizeof (struct InputEvent),MEMF_CLEAR|MEMF_PUBLIC);
  487.  
  488.         if (!thisie)
  489.         {
  490.             FreeVec (junkbuf);
  491.             FreeIEs(firstie);
  492.             return (0);
  493.         }
  494.         
  495.         if (oldie)
  496.             oldie->ie_NextEvent=thisie;
  497.         else
  498.             firstie=thisie;
  499.  
  500.         /* PARANOIA! */
  501.         //thisie->ie_NextEvent=0;
  502.  
  503.         thisie->ie_Class=IECLASS_RAWKEY;
  504.         //thisie->ie_SubClass=0;
  505.         thisie->ie_Code=(*(junkbuf+cnt)>>8) & 255;
  506.         thisie->ie_Qualifier=*(junkbuf+cnt) & 255;
  507.  
  508.         if (oldie)
  509.         {
  510.             thisie->ie_position.ie_dead.ie_prev1DownCode=oldie->ie_Code;
  511.             thisie->ie_position.ie_dead.ie_prev1DownQual=oldie->ie_Qualifier;
  512.         }
  513.  
  514.         if (grandpa)
  515.         {
  516.             thisie->ie_position.ie_dead.ie_prev2DownCode=grandpa->ie_Code;
  517.             thisie->ie_position.ie_dead.ie_prev2DownQual=grandpa->ie_Qualifier;
  518.         }
  519.     }
  520.  
  521.     FreeVec (junkbuf);
  522.     return (firstie);
  523. }
  524.  
  525. struct Window *GetConWindow (struct Process *ConProcess,struct MsgPort *MyPort)
  526. {
  527.     struct Window *ResultWindow;
  528.     struct MsgPort *con;
  529.     struct StandardPacket packet;
  530.     struct InfoData id;
  531.  
  532.     ResultWindow=0L;
  533.  
  534.     if (ConProcess->pr_Task.tc_Node.ln_Type == NT_PROCESS)
  535.     {
  536.         con=ConProcess->pr_ConsoleTask;
  537.  
  538.         if (con)
  539.         {
  540.             packet.sp_Msg.mn_Node.ln_Name=(char *)&(packet.sp_Pkt);
  541.             packet.sp_Pkt.dp_Link=&(packet.sp_Msg);
  542.             packet.sp_Pkt.dp_Port=MyPort;
  543.             packet.sp_Pkt.dp_Type=ACTION_DISK_INFO;
  544.             packet.sp_Pkt.dp_Arg1=((ULONG) &id) >> 2;
  545.             PutMsg (con,(struct Message *)&packet);
  546.             WaitPort (MyPort);
  547.             ResultWindow=(struct Window *)id.id_VolumeNode;
  548.         }
  549.     }
  550.  
  551.     return (ResultWindow);
  552. }
  553.  
  554. long AntiBlocking (APTR MyConsoleTask)
  555. {
  556.     long winusers=0;
  557.     long cnt,max;
  558.  
  559.     Forbid();
  560.  
  561.     max=MaxCli()+1;
  562.  
  563.     for (cnt=1;cnt < max;cnt++)
  564.     {
  565.         struct Process *ThisProc;
  566.  
  567.         if (ThisProc=FindCliProc (cnt))
  568.         {
  569.             if (ThisProc->pr_ConsoleTask == MyConsoleTask)
  570.                 winusers++;
  571.         }
  572.     }
  573.  
  574.     Permit();
  575.  
  576.     return (winusers);
  577. }
  578.  
  579. void MegaAbort (struct IOStdReq *AbortMe)
  580. {
  581.     AbortIO ((struct IORequest *)AbortMe);
  582.     WaitIO ((struct IORequest *)AbortMe);
  583.     SetSignal (0L,1L << (AbortMe->io_Message.mn_ReplyPort->mp_SigBit));
  584. }
  585.  
  586. void LaunchRequest (long secs,long micros,struct timerequest *mytimerio)
  587. {
  588.     timerio->tr_node.io_Command=TR_ADDREQUEST;
  589.     timerio->tr_time.tv_secs=secs;
  590.     timerio->tr_time.tv_micro=micros;
  591.     SendIO ((struct IORequest *)mytimerio);
  592. }
  593.